home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume7 / man.7300 < prev    next >
Encoding:
Text File  |  1989-07-21  |  12.3 KB  |  398 lines

  1. Newsgroups: comp.sources.misc
  2. organization: ICUS Software Systems, Islip, NY
  3. subject: v07i091: Enhanced man(1) utility - especially for those without one
  4. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5. Reply-To: gil@limbic.UUCP (Gil Kloepfer Jr.)
  6.  
  7. Posting-number: Volume 7, Issue 91
  8. Submitted-by: gil@limbic.UUCP (Gil Kloepfer Jr.)
  9. Archive-name: man.7300
  10.  
  11. [Note that this has also been posted to unix-pc.sources]
  12. [[Crossposting between unmoderated and moderated groups is discouraged
  13.   in general.  ++bsa]]
  14.  
  15. Here is a utility that I hacked for my UNIX-pc without a decent man(1)
  16. utility.  I've heard that some others are also missing this utility,
  17. or have a braindamaged one.  I'm passing it along to comp.sources.misc
  18. in case others have a use for it.  I've only tested it on my UNIX-pc,
  19. but it should work with little or no changes on most unices (plural
  20. of unix?).
  21.  
  22. Note that to link the program, you'll need Doug Gwyn's dirent package,
  23. previously posted to the net.  All other information is in the README
  24. file, packaged with the shar.
  25.  
  26. ========
  27. | Gil Kloepfer, Jr.
  28. | ICUS Software Systems/Bowne Management Systems (depending on where I am)
  29. | ...icus!limbic!gil   or    gil@icus.islp.ny.us
  30.  
  31. #! /bin/sh
  32. # This is a shell archive.  Remove anything before this line, then unpack
  33. # it by saving it into a file and typing "sh file".  To overwrite existing
  34. # files, type "sh file -c".  You can also feed this as standard input via
  35. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  36. # will see the following message at the end:
  37. #        "End of shell archive."
  38. # Contents:  README man.c
  39. # Wrapped by gil@limbic on Wed Jul 12 13:21:43 1989
  40. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  41. if test -f README -a "${1}" != "-c" ; then 
  42.   echo shar: Will not over-write existing file \"README\"
  43. else
  44. echo shar: Extracting \"README\" \(2273 characters\)
  45. sed "s/^X//" >README <<'END_OF_README'
  46. XREADME file for man v1.0  -- Last updated 7/12/89
  47. X
  48. XThe following is my interpretation of the UNIX "man" command.  Although
  49. Xit isn't very robust, it does handle some very useful cases which occur
  50. Xwhen trying to get stored manual pages, such as:
  51. X
  52. X[from the source]
  53. X
  54. X    o  You can "man" compressed manual pages 
  55. X    o  You don't have to know if the manual
  56. X       pages are unformatted (/usr/man/man?)
  57. X       or formatted (/usr/man/cat?).
  58. X    o  You don't have to know what section
  59. X       the manual page is in (and it tells you
  60. X       which one)
  61. X    o  You get automatic paging when you
  62. X       invoke man from a tty
  63. X
  64. X
  65. XI didn't bother with a makefile since there is only one source file
  66. Xhere.  It compiles by:
  67. X
  68. X    $ cc -O -o man man.c -ldirent -s
  69. X
  70. XUse whatever other favorite options you like.  Install it in /usr/local/bin
  71. Xor /usr/lbin (whichever you use on your system).  It does not require any
  72. Xs-bits to be set.
  73. X
  74. XIMPORTANT NOTE:  As noted above, this requires that Doug Gwyn's "dirent"
  75. Xsubroutine library be installed.  I didn't include it with this distribution!
  76. XIf you require it, drop me a note.  If I get enough notes, I'll repost the
  77. Xsource.
  78. X
  79. XCONFIGURATION HINTS:  In the source there are 3 "#define"s which define
  80. Xthe pager, compressed file "cat" program, and the name of your nroff
  81. Xprogram.  These should be defined however you like them, or undefined if
  82. Xyou don't have them.  There are two "#define"s which define where the
  83. Xmanual pages are located -- in /usr/man/man? and /usr/man/cat? .  Set
  84. Xthese to the way your system is configured.
  85. X
  86. XOne more bit of background-- as you might notice from some of the code,
  87. Xthis program was a bit of a hack.  I was tired of not having "man" work
  88. Xthis way, so I hacked this up quickly.  There were several individuals
  89. Xinterested in the program, so I decided to post it.  In any event, if
  90. Xyou think it needs more functionality or should be modified to do a
  91. Xparticular thing differently, don't complain to me about it.  Make the
  92. Xchange and send me the diffs so I can get some patches on the net and
  93. Xeveryone can benefit!
  94. X
  95. XAlso note that the code has only been tested and used on my UNIX-pc, but
  96. Xit seems that it should run under almost any Unix environment.
  97. X
  98. XHope this is of use to lots of you.
  99. X
  100. X
  101. XGil Kloepfer, Jr.   ICUS Software Systems
  102. X...!icus!limbic!gil
  103. END_OF_README
  104. if test 2273 -ne `wc -c <README`; then
  105.     echo shar: \"README\" unpacked with wrong size!
  106. fi
  107. # end of overwriting check
  108. fi
  109. if test -f man.c -a "${1}" != "-c" ; then 
  110.   echo shar: Will not over-write existing file \"man.c\"
  111. else
  112. echo shar: Extracting \"man.c\" \(7578 characters\)
  113. sed "s/^X//" >man.c <<'END_OF_man.c'
  114. X/***************************************************************************\
  115. X * File name:        man.c                              *
  116. X *                                       *
  117. X * Purpose:        Provide a better user interface to read the manual *
  118. X *            pages.                           *
  119. X *                                       *
  120. X * Programmer:        Gil Kloepfer, Jr.  ICUS Software Systems       *
  121. X *                                       *
  122. X * Revision history:     8-Jun-89  0.1     Program created [Beta release]       *
  123. X *             12-Jul-89  1.0     Program released
  124. X *                                       *
  125. X * Restrictions:    Requires Doug Gwyn's "dirent" subroutine package.  *
  126. X *            Optionally requires "compress" package, as well    *
  127. X *            as links to it called "zcat," and a text pager     *
  128. X *            such as    "more."  Having "nroff" is also a plus.       *
  129. X *                                       *
  130. X *            Program has been tested on the UNIX-pc 3B1.  It    *
  131. X *            should work on other systems, but this hasn't been *
  132. X *            tested.                           *
  133. X *                                       *
  134. X * Usage:        Invoked from the shell or a script by:           *
  135. X *                $ man [section] command               *
  136. X *                                       *
  137. X *            This manual page interface provides the following  *
  138. X *            features:                       *
  139. X *                 o  You can "man" compressed manual pages   *
  140. X *                o  You don't have to know if the manual    *
  141. X *                   pages are unformatted (/usr/man/man?)   *
  142. X *                   or formatted (/usr/man/cat?).       *
  143. X *                o  You don't have to know what section     *
  144. X *                   the manual page is in (and it tells you *
  145. X *                   which one)                   *
  146. X *                o  You get automatic paging when you       *
  147. X *                   invoke man from a tty           *
  148. X *                                       *
  149. X * Compiled by:        $ cc -v -O -o man man.c -ldirent -s           *
  150. X *                                       *
  151. X * Copyright/        (C) 1989 Gil Kloepfer, Jr., ICUS Software Systems  *
  152. X * Disclaimer:        All Rights Reserved                   *
  153. X *                                       *
  154. X *            Permission is granted to use, copy, or redistribute*
  155. X *            this software provided that this header in its     *
  156. X *            entirety is kept in the source code, that all      *
  157. X *            copyright notices are left intact, and that it is  *
  158. X *            not distributed or used for monetary gain of any   *
  159. X *            kind without the express, written permission of    *
  160. X *            the copyright holder(s).  Furthermore, if this     *
  161. X *            software is modified, all changes should be mailed *
  162. X *            to icus!gil.                       *
  163. X *                                       *
  164. X *            The user of this program agrees and understands    *
  165. X *            that this software is distributed on an "as-is"    *
  166. X *            basis, and shall not use this program as the basis *
  167. X *            for any claims, now or in the future, against      *
  168. X *            any individual, organization, or entity.       *
  169. X\***************************************************************************/
  170. X
  171. X#include <stdio.h>
  172. X#include <sys/types.h>
  173. X#include <dirent.h>
  174. X#include <sys/stat.h>
  175. X
  176. X#define    PROCD        "/usr/man/cat"    /* dir prefix for preformatted pages */
  177. X#define    NPROCD        "/usr/man/man"    /* dir prefix for nroff format pages */
  178. X#define    MAXPATH        128        /* maximum size of path to man page */
  179. X
  180. X/* undefine any of the following if your system doesn't have them */
  181. X
  182. X#define    TYPECOMP    "/usr/bin/zcat"    /* command to display a compressed file */
  183. X#define    FORMAT        "/usr/bin/nroff -man" /* command to format a manual page */
  184. X#define    PAGER        "/usr/bin/more"    /* system command to page a file */
  185. X
  186. X/* Don't play with these constants!! */
  187. X#define    C_PROC        1
  188. X#define    C_NPROC        2
  189. X
  190. X
  191. Xmain(argc,argv)
  192. Xint argc;
  193. Xchar *argv[];
  194. X{
  195. X    int    argno, section, kind, lookup();
  196. X    char    command[20], pagename[MAXPATH];
  197. X
  198. X    /* Process the command line arguments */
  199. X
  200. X    switch(argc) {
  201. X    case 2:  /* just the command name */
  202. X        strncpy(command,argv[1],20);
  203. X        section=0;
  204. X        break;
  205. X
  206. X    case 3:  /* the section and command name */
  207. X        sscanf(argv[1], "%d", §ion);
  208. X        strncpy(command,argv[2],20);
  209. X        break;
  210. X
  211. X    default:  /* invalid .. display the usage statement */
  212. X        fprintf(stderr,"usage: %s [section] command\n", argv[0]);
  213. X        exit(1);
  214. X    }
  215. X
  216. X    /*
  217. X     * If the section is not specified explicitly, try to find
  218. X     * the manual page in the first directory where it's encountered.
  219. X     */
  220. X
  221. X    if (section == 0) {
  222. X        for (section=1; section<=8; section++)
  223. X            if (lookup(command,section,pagename,&kind)) {
  224. X                fprintf(stderr,"%s: assuming %s from section %d\n",
  225. X                    argv[0], command, section);
  226. X                printpage(pagename,kind);
  227. X                exit(0);
  228. X            }
  229. X        fprintf(stderr,"%s: cannot find %s in the manual\n",
  230. X                argv[0], command);
  231. X        exit(2);
  232. X    }
  233. X
  234. X    /*
  235. X     * If the user specified a section, then see if we can find it
  236. X     * there .. if so, print the page
  237. X     */
  238. X
  239. X    if (lookup(command,section,pagename,&kind)) {
  240. X        printpage(pagename,kind);
  241. X        exit(0);
  242. X    } else {
  243. X        fprintf(stderr,"%s: cannot find %s in section %d\n",
  244. X            argv[0], command, section);
  245. X        exit(2);
  246. X    }
  247. X}
  248. X
  249. X
  250. X/*
  251. X * Function lookup returns 0 on failure and 1 on success.  It will look
  252. X * through the directories for section and try to find the manual page
  253. X * for command.  If it finds it, the entire filename is returned as
  254. X * pagename.  "kind" passes along whether the name was found in the
  255. X * processed or unprocessed directory phases
  256. X */
  257. X
  258. Xint lookup(command,section,pagename,kind)
  259. Xchar *command, *pagename;
  260. Xint section, *kind;
  261. X{
  262. X    int    passno, cmpman();
  263. X    char    fullpath[MAXPATH];
  264. X    DIR    *mdir;
  265. X    struct dirent *dentry;
  266. X
  267. X    /*
  268. X     * Look through the formatted directory first to see if we
  269. X     * can get one that's formatted.  The second pass gets
  270. X     * the formatted directory.  This looks kludgy, but it's
  271. X     * pretty neat nevertheless.
  272. X     */
  273. X
  274. X    for (passno=1; passno<=2; passno++) {
  275. X        switch(passno) {
  276. X        case 1:  /* check formatted directory */
  277. X            sprintf(fullpath, "%s%d", PROCD, section);
  278. X            *kind = C_PROC;
  279. X            break;
  280. X
  281. X        case 2:  /* check unformatted directory */
  282. X            sprintf(fullpath, "%s%d", NPROCD, section);
  283. X            *kind = C_NPROC;
  284. X            break;
  285. X        }
  286. X
  287. X        if ((mdir=opendir(fullpath)) != NULL)
  288. X            while ((dentry=readdir(mdir)) != NULL)
  289. X                if (cmpman(dentry->d_name,command) == 0) {
  290. X                    closedir(mdir);
  291. X                    sprintf(pagename, "%s/%s", fullpath,
  292. X                        dentry->d_name);
  293. X                    return(1);
  294. X                }
  295. X
  296. X        closedir(mdir);
  297. X    }
  298. X    return(0);
  299. X}
  300. X
  301. X
  302. X/*
  303. X * Compare name with command and see if it matches before the period
  304. X * so we can crown it the matching manual page for command
  305. X */
  306. X
  307. Xint cmpman(name,command)
  308. Xchar *name, *command;
  309. X{
  310. X    while ((*name == *command) && *name != '\0' && *command != '\0') {
  311. X        name++;
  312. X        command++;
  313. X    }
  314. X
  315. X    if (*name == '.' && *command == '\0') return(0);  /* OK */
  316. X    if (*command == *name) return(0);  /* also OK */
  317. X
  318. X    return(1);  /* all other cases fail */
  319. X}
  320. X
  321. X
  322. X/*
  323. X * Printpage prints a manual page.  It formats the page depending on
  324. X * where it comes from, and invokes the system pager depending on
  325. X * whether output is to a tty or a file/pipe
  326. X */
  327. X
  328. Xprintpage(pageloc,form)
  329. Xchar *pageloc;
  330. Xint form;
  331. X{
  332. X    int    compress, endstr, ttypage;
  333. X    char    cmdline[512];
  334. X
  335. X    /* See if we're dealing with a compressed file (.Z) */
  336. X
  337. X    endstr=strlen(pageloc);
  338. X    if (pageloc[endstr-2]=='.' && pageloc[endstr-1]=='Z')
  339. X        compress=1;
  340. X    else
  341. X        compress=0;
  342. X
  343. X#ifndef    TYPECOMP
  344. X    if (compress) {
  345. X        fprintf(stdout,"%s: compressed files not supported\n",
  346. X                argv[0]);
  347. X        exit(2);
  348. X    }
  349. X#endif
  350. X
  351. X    /* If we're a tty, page this using whatever our pager is */
  352. X
  353. X#ifdef PAGER
  354. X    if (isatty(1))
  355. X        ttypage=1;
  356. X    else
  357. X        ttypage=0;
  358. X#else
  359. X    ttypage=0;
  360. X#endif
  361. X
  362. X    /*
  363. X     * Setup command line.  This is some really sick code, but
  364. X     * how else are we to do it?  I can think of only one way, but
  365. X     * it's kind of wasteful of system resources...
  366. X     */
  367. X
  368. X    if (compress) {
  369. X        if (form == C_NPROC)
  370. X            sprintf(cmdline, "%s %s | %s", TYPECOMP, pageloc, FORMAT);
  371. X        else
  372. X            sprintf(cmdline, "%s %s", TYPECOMP, pageloc);
  373. X    } else {
  374. X        if (form == C_NPROC)
  375. X            sprintf(cmdline, "%s %s", FORMAT, pageloc);
  376. X        else
  377. X            sprintf(cmdline, "/bin/cat %s", pageloc);
  378. X    }
  379. X
  380. X    if (ttypage) {
  381. X        strcat(cmdline," | ");
  382. X        strcat(cmdline,PAGER);
  383. X    }
  384. X
  385. X    /* Invoke command */
  386. X
  387. X    system(cmdline);
  388. X}
  389. END_OF_man.c
  390. if test 7578 -ne `wc -c <man.c`; then
  391.     echo shar: \"man.c\" unpacked with wrong size!
  392. fi
  393. # end of overwriting check
  394. fi
  395. echo shar: End of shell archive.
  396. exit 0
  397.  
  398.